package net.techfuser.orderstatusreport;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description:
 * @Author 左龙龙
 * @Date 21-4-21
 * @Version 1.0
 **/
@Slf4j
public class OrderStatusOplogAnalysis {

    /**
     * 特征检查
     */
    public static void check(JSONObject order, Map<String, Integer> status) {
        if (null == order) {
            return;
        }

        if (order.containsKey("confirm_time")) {
            status.put("confirm_time", status.getOrDefault("confirm_time", 0) + 1);

            if (order.containsKey("order_status")) {
                String order_status = order.getJSONObject("order_status").getString("center");
                if (!"15".equals(order_status)) {
                    status.put("valid_order", status.getOrDefault("valid_order", 0) + 1);
                }
            }
        }

        if (order.containsKey("stocking_time")) {
            status.put("stocking_time", status.getOrDefault("stocking_time", 0) + 1);
        }

        if (order.containsKey("complete_time")) {
            status.put("complete_time", status.getOrDefault("complete_time", 0) + 1);
        }

        if (order.containsKey("cancel_time")) {
            status.put("cancel_time", status.getOrDefault("cancel_time", 0) + 1);
        }

    }


    /**
     * 分析 oplog 记录
     */
    public static List<OrderStatus> analysis(List<JSONObject> oplogs) {
        List<OrderStatus> change = new ArrayList<>();
        if(null == oplogs || oplogs.isEmpty()){
            return change;
        }

        Map<String, Integer> countMap = new HashMap<>();
        JSONObject order = null;
        for (JSONObject row : oplogs) {
            String op = row.getString("op");
            switch (op){
                case "i": order = row.getJSONObject("o"); break;
                case "u": {
                    JSONObject o = row.getJSONObject("o");
                    for (String key : o.keySet()) {
                        if ("$set".equals(key)) {
                            order.putAll(o.getJSONObject(key));
                        } else if ("$unset".equals(key)) {
                            JSONObject unsetObj = o.getJSONObject(key);
                            for (String k : unsetObj.keySet()) {
                                order.remove(k);
                            }
                        } else {
                            log.warn("未知的操作: {}", row.toJSONString());
                        }
                    }
                    break;
                }
                case "d": {
                    order = null;
                    break;
                }
                default: log.warn("未识别的操作: {}", row.toJSONString());
            }


            check(order, countMap);
        }

        if (order == null) {
            log.warn("oplog数据异常", oplogs);
            return change;
        }


//        // TODO  测试部分企业
//        if (1597145301932262400L != order.getLongValue("ent_id")) {
//            return change;
//        }


        SimpleDateFormat sdf = new SimpleDateFormat();
        String order_status = order.getJSONObject("order_status").getString("center");
        int factor = (1 == countMap.getOrDefault("cancel_time", 0)) ? -1 : 1;
        double total_sale_value = order.getDoubleValue("total_sale_value");
        Map<String, OrderStatus> temp = new HashMap<>();
        for (String key : countMap.keySet()) {
            Integer count = countMap.get(key);

            if (count == 1 || factor == -1) {
                OrderStatus row = null;
                Date date = null;
                if (key.equals("confirm_time")) {
                    date = order.getDate("confirm_time");
                    row = temp.getOrDefault(sdf.format(date), new OrderStatus());
                    row.confirm_order_num = 1 * factor;
                    row.confirm_sale_value =  total_sale_value * factor;
                } else if (key.equals("valid_order")) {
                    date = order.getDate("confirm_time");
                    row = temp.getOrDefault(sdf.format(date), new OrderStatus());
                    row.valid_order_num = 1 * factor;
                    row.valid_sale_value = total_sale_value * factor;
                } else if (key.equals("stocking_time")) {
                    date = order.getDate("stocking_time");
                    row = temp.getOrDefault(sdf.format(date), new OrderStatus());
                    row.package_order_num = 1 * factor;
                    row.package_sale_value = total_sale_value * factor;
                } else if (key.equals("complete_time")) {
                    date = order.getDate("complete_time");
                    row = temp.getOrDefault(sdf.format(date), new OrderStatus());
                    row.complate_order_num = 1 * factor;
                    row.complate_sale_value = total_sale_value * factor;
                } else if (key.equals("cancel_time")) {
                    date = order.getDate("cancel_time");
                    row = temp.getOrDefault(sdf.format(date), new OrderStatus());
                    row.cancel_order_num = 1;
                    row.cancel_sale_value = total_sale_value;
                }

                row.date = date;
                row.ent_id = order.getLongValue("ent_id");
                row.region_code = order.getString("region_code");
                row.region_name = order.getString("region_name");
                row.channel_keyword = order.getString("channel_keyword");
                row.channel_sheetno = order.getString("channel_sheetno");
                row.order_status = order_status;

                if(!temp.containsKey(sdf.format(row.date))){
                    change.add(row);
                }
                temp.put(sdf.format(row.date), row);
            }
        }

        return change;
    }


}